﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using Pharmacy.Ultilities.Localization;
using Pharmacy.Ultilities;
using Pharmacy.Ultilities.Configurations;
using DevExpress.LookAndFeel;
using Pharmacy.ExceptionHandling;
using System.Threading;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.ExceptionHandling;
using PharmacyPharnet.MasterData;

namespace PharmacyPharnet
{
    static class Program
    {
        #region Declarations
        static FrmLogin frmLogin;
        static FrmMain frmMain;
        private static bool flLogin;
        #endregion

        #region Constructors
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            // TODO: Handle unhandled exceptions
            Application.ThreadException += Application_ThreadException;
            AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;

            DevExpress.UserSkins.OfficeSkins.Register();
            DevExpress.UserSkins.BonusSkins.Register();
            DevExpress.Skins.SkinManager.EnableFormSkins();

            // Apply skin from config
            UserLookAndFeel.Default.SetSkinStyle(ConfigManager.DIOConfig[Constant.SKINSTYLE]);

            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            // Initialize connection string
            Global.CurrentConnectionString = ConfigManager.DIOConfig.ConnectionString;

            // Initialize localize
            LocalizerText.InitializeMultiLanguage();

            // Show form login
            frmLogin = new FrmLogin();
            frmLogin.LoadError += new EventHandler(frmLogin_LoadError);
            frmLogin.Authenticated += frmLogin_Authenticated;
            Application.Run(frmLogin);

            //FrmMasterItem_List frm = new FrmMasterItem_List();
            //Application.Run(frm);
        }

        static void frmLogin_LoadError(object sender, EventArgs e)
        {
            using (FrmConfiguration frmConfig = new FrmConfiguration() { ShowInTaskbar = true })
            {
                frmConfig.ShowDialog();
            }

            if (sender is FrmLogin) ((FrmLogin)sender).IsOnLoadErrorEventHandled = true;
        }

        #endregion

        #region Methods

        #endregion

        #region Event Handlers
        static void frmLogin_Authenticated(Pharmacy.Data.Entity.User user)
        {
            flLogin = false;
            if (frmLogin != null)
            {
                frmLogin.HideThis();
            }
            frmMain = new FrmMain();
            frmMain.LoginEvent += new FrmMain.LoginHandler(frmMain_LoginEvent);
            frmMain.FormClosing += frmMain_FormClosing;
            frmMain.Show();
        }

        static void frmMain_LoginEvent()
        {
            flLogin = true;
            if (frmLogin != null)
            {
                frmLogin.ShowThis();
            }
            if (frmMain != null)
            {
                frmMain.Hide();
                frmMain.Close();
            }
        }

        static void frmMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (!e.Cancel && !flLogin)
            {
                if (frmLogin != null)
                    frmLogin.Close();
            }
        }

        /// <summary>
        /// Handle exception base on policies. 
        /// <list type="1">
        /// <item>Policy "General": write log and re-throw exception</item>
        /// <item>Policy "Unhandled": write log, show MessageBox and hide the exception</item>
        /// </list>
        /// </summary>
        /// <param name="ex">The exception to be handled.</param>
        /// <param name="policy">The policy which will be applied.</param>
        public static void HandleException(Exception ex, string policy)
        {
            Boolean rethrow = false;

            try
            {
                rethrow = ExceptionHandler.ExceptionMgr.HandleException(ex, policy);
            }
            catch (Exception innerEx)
            {
                string errorMsg = String.Format("An unexpected exception occured while calling HandleException with policy '{0}'. ", policy);
                errorMsg += Environment.NewLine + innerEx;
                MessageBox.Show(errorMsg, "Application Error", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                throw ex;
            }

            if (rethrow)
            {
                // WARNING: This will truncate the stack of the exception
                throw ex;
            }
            else
            {
                //An unhandled exception occurred and has been logged. Please contact support.
                MessageBox.Show(PharmacyPharnet.Properties.Resources.UnhandledErrorWarning);
            }
        }

        static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
        {
            HandleException(e.Exception, ExceptionHandler.EX_POLICY_UNHANDLED);
        }

        static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            if (e.ExceptionObject is System.Exception)
            {
                HandleException((System.Exception)e.ExceptionObject, ExceptionHandler.EX_POLICY_UNHANDLED);
            }
        }
        #endregion
    }
}
